package net.xxcxcxcx.xc_enhancedmob.component;

import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.PlayerLookup;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.entity.EntityData;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.world.LocalDifficulty;
import net.minecraft.world.ServerWorldAccess;
import net.xxcxcxcx.xc_enhancedmob.enhanced.level.Level;
import net.xxcxcxcx.xc_enhancedmob.enhanced.rarity.Rarity;
import net.xxcxcxcx.xc_enhancedmob.skills.Skill;
import net.xxcxcxcx.xc_enhancedmob.skills.SkillHelper;
import net.xxcxcxcx.xc_enhancedmob.skills.SkillRarity;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

import static net.xxcxcxcx.xc_enhancedmob.EnhancedMobMod.MoreTitleIdentifier;

/**
 * 精英实体储存的数据
 */
public class EnhancedBaseComponent implements BaseComponent {
    private final MobEntity mobEntity;//生物实体本身
    private Skill environment = null;
    private Rarity MobRarity = Rarity.Unknown;//初始化稀有度是未知的状态
    private int MobLevel = 0;//初始化等级是0
    private boolean Settitle = false;//是否设置了生物名称
    private boolean IncreaseAttribute = false;//是否增强了生物
    private List<Text> moretext;//更多文本
    private boolean dirtytitle = false;//是否需要重新同步文本
    private List<Skill> skills = null;

    public EnhancedBaseComponent(MobEntity mob) {
        mobEntity = mob;
    }//构造函数

    public Rarity getRarity() {
        return MobRarity;
    }//获取稀有度信息

    public void setRarity(Rarity r) {
        MobRarity = r;
    }//设置稀有度信息

    public int getMobLevel() {
        return MobLevel;
    }//获得生物等级信息

    public void setMobLevel(int a) {
        MobLevel = a;
    }//设置生物等级信息

    private void setTitle() {
        getMobEntity().setCustomName(getTitle());
    }//设置生物名称

    private void setMoreTitle() {
        setMoreTitle(getMoreTitle());
    }//设置多行文本

    public List<Text> getMoretext() {
        return moretext;
    }//获取多行文本

    private List<Text> getMoreTitle() {
        List<Text> textList = new ArrayList<>();
        if (hasSkills() && !(getSkills().size() == 1 && getEnvironment() != null)) {
            LiteralText literalText = new LiteralText("");
            List<Skill> skillList = getSkills();
            for (int i = 0, j = 0; i < skillList.size(); i++) {
                if (skillList.get(i) == getEnvironment()) continue;
                j++;
                if (j != 0 && j % 5 == 0) {
                    textList.add(literalText);
                    literalText = new LiteralText("");
                }
                literalText.append(skillList.get(i).getText());
                if (j % 5 != 4 && j != skillList.size() - 1) literalText.append(" ");
            }
            textList.add(literalText);
        }
        return textList;
    }//生成多行文本

    public void setMoreTitle(List<Text> list) {
        moretext = list;
        if (!getMobEntity().world.isClient) setDirtytitle(true);
    }//设置多文本

    public boolean hasMoreText() {
        return moretext != null && !moretext.isEmpty();
    }//判断是否存在多行文本

    public boolean getDirtytitle() {
        return dirtytitle;
    }//查询多文本是否要更新

    public void setDirtytitle(boolean d1) {
        dirtytitle = d1;
    }//设置多文本是否要更新

    public void Update() {
        if (getMobEntity().world != null && getMobEntity().world instanceof ServerWorld && hasMoreText()) {
            PacketByteBuf buf = PacketByteBufs.create();
            buf.writeInt(getMobEntity().getEntityId());
            buf.writeInt(moretext.size());
            for (Text text : moretext) {
                buf.writeText(text);
            }
            for (ServerPlayerEntity player : PlayerLookup.tracking(getMobEntity())) {
                ServerPlayNetworking.send(player, MoreTitleIdentifier, buf);
            }
        }
    }//更新多文本

    public Text getTitle() {
        LiteralText literalText = new LiteralText("");
        if (getMobLevel() != -1) literalText.append(Level.getText(getMobLevel())).append(" ");
        if (getRarity() != Rarity.Unknown) literalText.append(getRarity().getText()).append(" ");
        if (getEnvironment() != null) literalText.append(getEnvironment().getText()).append(" ");
        literalText.append(getMobEntity().getDisplayName().getString());
        return (literalText);
    }//获取生物名称

    public boolean hasSkills() {
        return skills != null && !skills.isEmpty();
    }//是否有技能

    public List<Skill> getSkills() {
        return skills;
    }//获取技能列表

    public void setSkills(List<Skill> list) {
        skills = list;
        list.sort((a, b) -> {
            if (a.getEffectiveSequence() != b.getEffectiveSequence()) {
                return a.getEffectiveSequence() - b.getEffectiveSequence();
            } else if (a.getSkillRarity().count == b.getSkillRarity().count) {
                return a.getName().compareTo(b.getName());
            } else return a.getSkillRarity().count - b.getSkillRarity().count;
        });
    }//设置技能列表

    public void addSkills(Skill skill) {
        skills.add(skill);
        skills.sort((a, b) -> {
            if (a.getEffectiveSequence() != b.getEffectiveSequence()) {
                return a.getEffectiveSequence() - b.getEffectiveSequence();
            } else if (a.getSkillRarity().count == b.getSkillRarity().count) {
                return a.getName().compareTo(b.getName());
            } else return a.getSkillRarity().count - b.getSkillRarity().count;
        });
    }//添加技能

    private boolean CanEnhanced() {
        return getMobEntity().world != null
                && !getMobEntity().world.isClient
                && (getRarity() == Rarity.Unknown || getMobLevel() == 0)
                && !getMobEntity().hasCustomName();
    }//生物是否可以强化

    private void increaseAllAttribute() {
        Level.increaseAttribute(getMobEntity(), getMobLevel());
        Rarity.increaseAttribute(getMobEntity(), getRarity());
        getMobEntity().setHealth((float) getMobEntity().getAttributeValue(EntityAttributes.GENERIC_MAX_HEALTH));
    }//增强生物函数

    @Override
    public void writeCustomDataToNbt(NbtCompound nbt) {
        NbtCompound MobEnhancedData = new NbtCompound();
        NbtCompound MobRarityData = new NbtCompound();
        MobRarityData.putString("MobRarityData", getRarity().toString());
        MobEnhancedData.put("MobRarity", MobRarityData);

        NbtCompound MobLevelData = new NbtCompound();
        MobLevelData.putInt("MobLevelData", getMobLevel());
        MobEnhancedData.put("MobLevel", MobRarityData);

        NbtCompound MobSkillData = new NbtCompound();
        if (hasSkills()) {
            List<Skill> skillList = getSkills();
            for (int i = 0; i < skillList.size(); i++) {
                MobSkillData.put(skillList.get(i).getName(), skillList.get(i).getNbtCompound());
            }
        }
        MobEnhancedData.put("MobSkill", MobSkillData);

        MobEnhancedData.putBoolean("Settitle", Settitle);
        MobEnhancedData.putBoolean("IncreaseAttribute", IncreaseAttribute);
        nbt.put("MobEnhanced", MobEnhancedData);
    }

    @Override
    public void readCustomDataFromNbt(NbtCompound nbt) {
        if (nbt.contains("MobEnhanced")) {
            NbtCompound MobEnhancedData = nbt.getCompound("MobEnhanced");
            if (MobEnhancedData.contains("MobRarity")) {
                NbtCompound MobRarityData = MobEnhancedData.getCompound("MobRarity");
                setRarity(Rarity.valueOf(MobRarityData.getString("MobRarityData")));
            }
            if (MobEnhancedData.contains("MobLevel")) {
                NbtCompound MobLevel = MobEnhancedData.getCompound("MobLevel");
                setMobLevel(MobLevel.getInt("MobLevelData"));
            }
            if (MobEnhancedData.contains("MobSkill")) {
                NbtCompound MobLevel = MobEnhancedData.getCompound("MobSkill");
                setSkills(SkillHelper.makeSkillsfromNbt(MobLevel));
            }
            for (Skill skill : getSkills()) {
                if (skill.getSkillRarity() == SkillRarity.Environment) {
                    environment = skill;
                    break;
                }
            }
            Settitle = MobEnhancedData.getBoolean("Settitle");
            IncreaseAttribute = MobEnhancedData.getBoolean("IncreaseAttribute");
            if (Settitle) setMoreTitle();
        }
    }

    @Override
    public EntityData initialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt) {
        if (getMobEntity() != null && CanEnhanced()) {
            if (getRarity() == Rarity.Unknown) Rarity.random(this);
            if (getMobLevel() == 0) Level.random(this);
            SkillHelper.randomskills(this);
            if (getEnvironment() == null) SkillHelper.randomenvironmentskills(this);
            if (getRarity() != Rarity.Unknown) {
                if (!getMobEntity().hasCustomName() && !Settitle) {
                    setTitle();
                    setMoreTitle();
                    Settitle = true;
                }
                if (!IncreaseAttribute) {
                    increaseAllAttribute();
                    IncreaseAttribute = true;
                }
            }
        }
        return entityData;
    }

    public Skill getEnvironment() {
        return environment;
    }

    public void setEnvironment(Skill environment) {
        this.environment = environment;
        this.addSkills(environment);
    }

    public MobEntity getMobEntity() {
        return mobEntity;
    }
}
